import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bluetooth/BluetoothMsg.dart';
import 'package:flutter_bluetooth/flutterbluetooth.dart';
import 'package:flutterbluetooth_example/toast.dart';
import 'package:provider/provider.dart';

typedef ConnectBluetooth(BluetoothMsg btMsg);

class BluetoothButton extends StatelessWidget {

  final BluetoothNotifier bluetoothNotifier;
  final BluetoothListNotifier bluetoothListNotifier;
  final ConnectBluetooth connectBluetooth;
  final Color btOnColor;

  BluetoothButton(this.bluetoothNotifier, this.bluetoothListNotifier,
      this.connectBluetooth, {this.btOnColor = Colors.white});

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return ChangeNotifierProvider.value(
      value: bluetoothNotifier,
      builder: (context, _) =>
      Consumer<BluetoothNotifier>(builder: (context, bluetoothNotifier, _) {
        Color color = Colors.red;
        String label = "蓝牙状况不明";
        IconData icon = Icons.bluetooth_disabled;
        switch (bluetoothNotifier.bluetoothState) {
          case BluetoothMsg.STATE_NO_SUPPORT:
            color = Colors.red;
            label = "该设备不支持蓝牙";
            break;
          case BluetoothMsg.STATE_OFF:
            color = Colors.grey;
            label = "蓝牙未开启";
            break;
          case BluetoothMsg.STATE_TURNING_ON:
            color = Colors.grey;
            label = "正在开启蓝牙";
            break;
          case BluetoothMsg.STATE_ON:
            color = btOnColor;
            if (bluetoothNotifier.connectedBluetooth != null) {
              label = bluetoothNotifier.connectedBluetooth.name == null
                  ? bluetoothNotifier.connectedBluetooth.address
                  : bluetoothNotifier.connectedBluetooth.name;
              icon = Icons.bluetooth_connected;
            } else {
              label = "蓝牙未连接";
              icon = Icons.bluetooth;
            }
            break;
          case BluetoothMsg.STATE_TURNING_OFF:
            color = btOnColor;
            label = "正在关闭蓝牙";
            icon = Icons.bluetooth;
            break;
        }
        return FlatButton.icon(
            onPressed: () => tapBluetooth(context),
            icon: Icon(
              icon,
              color: color,
            ),
            label: Text(
              label,
              style: TextStyle(
                  color: color, fontSize: 15),
              maxLines: 1,
              overflow: TextOverflow.ellipsis,
            ));
      }),
    );
  }

  tapBluetooth(BuildContext context) async {
    switch (bluetoothNotifier.bluetoothState) {
      case BluetoothMsg.STATE_NO_SUPPORT:
        ToastUtil.show("该设备不支持蓝牙");
        break;
      case BluetoothMsg.STATE_OFF:
        FlutterBluetooth.openBluetooth();
        break;
      case BluetoothMsg.STATE_TURNING_ON:
        ToastUtil.show("蓝牙开启中，请稍后");
        break;
      case BluetoothMsg.STATE_ON:
        showChooseBlueTooth(context);
        break;
      case BluetoothMsg.STATE_TURNING_OFF:
        ToastUtil.show("蓝牙关闭中，请稍后");
        break;
    }
  }

  void showChooseBlueTooth(BuildContext context) async {
    BlueToothListPage blueToothListPage = BlueToothListPage(
        bluetoothListNotifier, bluetoothNotifier.connectedBluetooth?.address);
    FlutterBluetooth.startDiscovery();
    BluetoothMsg bluetoothMsg = await showDialog(
        context: context,
        child: AlertDialog(
          title: Text("请选择蓝牙"),
          content: Container(
            width: 100,
            height: 500,
            child: blueToothListPage,
          ),
        ));
    FlutterBluetooth.cancelDiscovery();
    if (bluetoothMsg != null) {
      connectBluetooth(bluetoothMsg);
    }
  }
}

class BluetoothNotifier extends ChangeNotifier {
  int _bluetoothState;
  BluetoothMsg _connectedBluetoothMsg;

  BluetoothNotifier(this._bluetoothState, this._connectedBluetoothMsg);

  set bluetoothState(int bluetoothState) {
    this._bluetoothState = bluetoothState;
    notifyListeners();
  }

  set connectedBluetooth(BluetoothMsg connectedBluetooth) {
    this._connectedBluetoothMsg = connectedBluetooth;
    notifyListeners();
  }

  int get bluetoothState => _bluetoothState;

  BluetoothMsg get connectedBluetooth => _connectedBluetoothMsg;
}

class BlueToothListPage extends StatelessWidget {
  final BluetoothListNotifier bluetoothListNotifier;
  final String selectedAddress;

  BlueToothListPage(this.bluetoothListNotifier,
      this.selectedAddress,);

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return ChangeNotifierProvider.value(
      value: bluetoothListNotifier,
        builder: (context, _) => Consumer<BluetoothListNotifier>(
          builder: (context, bluetoothListNotifier, _) {
            return ListView.builder(
              itemBuilder: (ctx, index) {
                BluetoothMsg btMsg = bluetoothListNotifier.get(index);
                return ListTile(
                  title: Text(
                    btMsg.name == null ? btMsg.address : btMsg.name,
                    style: TextStyle(
                        color: Colors.black),
                  ),
                  onTap: () => Navigator.pop(context, btMsg),
                );
              },
              itemCount: bluetoothListNotifier.length,
            );
          }),
    );
  }
}

class BluetoothListNotifier extends ChangeNotifier {
  List<BluetoothMsg> _list;

  BluetoothListNotifier() {
    _list = [];
  }

  add(BluetoothMsg btMsg) {
    if(_list.any((element) => element.address == btMsg.address))
      return;
    _list.add(btMsg);
    notifyListeners();
  }

  int get length => _list.length;

  BluetoothMsg get(int index) => _list[index];

  clear() {
    _list.clear();
    notifyListeners();
  }
}
